package pgsql

import (
	db_utils "gitee.com/zy_blue7/db-convert/db-utils"
	"strconv"
	"time"
)

type PgsqlTypes string

const (
	BOOL             PgsqlTypes = "BOOL"
	BYTEA            PgsqlTypes = "BYTEA"
	CHAR             PgsqlTypes = "CHAR"
	NAME             PgsqlTypes = "NAME"
	INT8             PgsqlTypes = "INT8"
	INT2             PgsqlTypes = "INT2"
	INT2VECTOR       PgsqlTypes = "INT2VECTOR"
	INT4             PgsqlTypes = "INT4"
	REGPROC          PgsqlTypes = "REGPROC"
	TEXT             PgsqlTypes = "TEXT"
	OID              PgsqlTypes = "OID"
	TID              PgsqlTypes = "TID"
	XID              PgsqlTypes = "XID"
	CID              PgsqlTypes = "CID"
	OIDVECTOR        PgsqlTypes = "OIDVECTOR"
	PG_DDL_COMMAND   PgsqlTypes = "PG_DDL_COMMAND"
	PG_TYPE          PgsqlTypes = "PG_TYPE"
	PG_ATTRIBUTE     PgsqlTypes = "PG_ATTRIBUTE"
	PG_PROC          PgsqlTypes = "PG_PROC"
	PG_CLASS         PgsqlTypes = "PG_CLASS"
	JSON             PgsqlTypes = "JSON"
	XML              PgsqlTypes = "XML"
	_XML             PgsqlTypes = "_XML"
	PG_NODE_TREE     PgsqlTypes = "PG_NODE_TREE"
	_JSON            PgsqlTypes = "_JSON"
	SMGR             PgsqlTypes = "SMGR"
	INDEX_AM_HANDLER PgsqlTypes = "INDEX_AM_HANDLER"
	POINT            PgsqlTypes = "POINT"
	LSEG             PgsqlTypes = "LSEG"
	PATH             PgsqlTypes = "PATH"
	BOX              PgsqlTypes = "BOX"
	POLYGON          PgsqlTypes = "POLYGON"
	LINE             PgsqlTypes = "LINE"
	_LINE            PgsqlTypes = "_LINE"
	CIDR             PgsqlTypes = "CIDR"
	_CIDR            PgsqlTypes = "_CIDR"
	FLOAT4           PgsqlTypes = "FLOAT4"
	FLOAT8           PgsqlTypes = "FLOAT8"
	ABSTIME          PgsqlTypes = "ABSTIME"
	RELTIME          PgsqlTypes = "RELTIME"
	TINTERVAL        PgsqlTypes = "TINTERVAL"
	UNKNOWN          PgsqlTypes = "UNKNOWN"
	CIRCLE           PgsqlTypes = "CIRCLE"
	_CIRCLE          PgsqlTypes = "_CIRCLE"
	MONEY            PgsqlTypes = "MONEY"
	_MONEY           PgsqlTypes = "_MONEY"
	MACADDR          PgsqlTypes = "MACADDR"
	INET             PgsqlTypes = "INET"
	_BOOL            PgsqlTypes = "_BOOL"
	_BYTEA           PgsqlTypes = "_BYTEA"
	_CHAR            PgsqlTypes = "_CHAR"
	_NAME            PgsqlTypes = "_NAME"
	_INT2            PgsqlTypes = "_INT2"
	_INT2VECTOR      PgsqlTypes = "_INT2VECTOR"
	_INT4            PgsqlTypes = "_INT4"
	_REGPROC         PgsqlTypes = "_REGPROC"
	_TEXT            PgsqlTypes = "_TEXT"
	_TID             PgsqlTypes = "_TID"
	_XID             PgsqlTypes = "_XID"
	_CID             PgsqlTypes = "_CID"
	_OIDVECTOR       PgsqlTypes = "_OIDVECTOR"
	_BPCHAR          PgsqlTypes = "_BPCHAR"
	_VARCHAR         PgsqlTypes = "_VARCHAR"
	_INT8            PgsqlTypes = "_INT8"
	_POINT           PgsqlTypes = "_POINT"
	_LSEG            PgsqlTypes = "_LSEG"
	_PATH            PgsqlTypes = "_PATH"
	_BOX             PgsqlTypes = "_BOX"
	_FLOAT4          PgsqlTypes = "_FLOAT4"
	_FLOAT8          PgsqlTypes = "_FLOAT8"
	_ABSTIME         PgsqlTypes = "_ABSTIME"
	_RELTIME         PgsqlTypes = "_RELTIME"
	_TINTERVAL       PgsqlTypes = "_TINTERVAL"
	_POLYGON         PgsqlTypes = "_POLYGON"
	_OID             PgsqlTypes = "_OID"
	ACLITEM          PgsqlTypes = "ACLITEM"
	_ACLITEM         PgsqlTypes = "_ACLITEM"
	_MACADDR         PgsqlTypes = "_MACADDR"
	_INET            PgsqlTypes = "_INET"
	BPCHAR           PgsqlTypes = "BPCHAR"
	VARCHAR          PgsqlTypes = "VARCHAR"
	DATE             PgsqlTypes = "DATE"
	TIME             PgsqlTypes = "TIME"
	TIMESTAMP        PgsqlTypes = "TIMESTAMP"
	_TIMESTAMP       PgsqlTypes = "_TIMESTAMP"
	_DATE            PgsqlTypes = "_DATE"
	_TIME            PgsqlTypes = "_TIME"
	TIMESTAMPTZ      PgsqlTypes = "TIMESTAMPTZ"
	_TIMESTAMPTZ     PgsqlTypes = "_TIMESTAMPTZ"
	INTERVAL         PgsqlTypes = "INTERVAL"
	_INTERVAL        PgsqlTypes = "_INTERVAL"
	_NUMERIC         PgsqlTypes = "_NUMERIC"
	PG_DATABASE      PgsqlTypes = "PG_DATABASE"
	_CSTRING         PgsqlTypes = "_CSTRING"
	TIMETZ           PgsqlTypes = "TIMETZ"
	_TIMETZ          PgsqlTypes = "_TIMETZ"
	BIT              PgsqlTypes = "BIT"
	_BIT             PgsqlTypes = "_BIT"
	VARBIT           PgsqlTypes = "VARBIT"
	_VARBIT          PgsqlTypes = "_VARBIT"
	NUMERIC          PgsqlTypes = "NUMERIC"
	REFCURSOR        PgsqlTypes = "REFCURSOR"
	_REFCURSOR       PgsqlTypes = "_REFCURSOR"
	REGPROCEDURE     PgsqlTypes = "REGPROCEDURE"
	REGOPER          PgsqlTypes = "REGOPER"
	REGOPERATOR      PgsqlTypes = "REGOPERATOR"
	REGCLASS         PgsqlTypes = "REGCLASS"
	REGTYPE          PgsqlTypes = "REGTYPE"
	_REGPROCEDURE    PgsqlTypes = "_REGPROCEDURE"
	_REGOPER         PgsqlTypes = "_REGOPER"
	_REGOPERATOR     PgsqlTypes = "_REGOPERATOR"
	_REGCLASS        PgsqlTypes = "_REGCLASS"
	_REGTYPE         PgsqlTypes = "_REGTYPE"
	RECORD           PgsqlTypes = "RECORD"
	CSTRING          PgsqlTypes = "CSTRING"
	ANY              PgsqlTypes = "ANY"
	ANYARRAY         PgsqlTypes = "ANYARRAY"
	VOID             PgsqlTypes = "VOID"
	TRIGGER          PgsqlTypes = "TRIGGER"
	LANGUAGE_HANDLER PgsqlTypes = "LANGUAGE_HANDLER"
	INTERNAL         PgsqlTypes = "INTERNAL"
	OPAQUE           PgsqlTypes = "OPAQUE"
	ANYELEMENT       PgsqlTypes = "ANYELEMENT"
	_RECORD          PgsqlTypes = "_RECORD"
	ANYNONARRAY      PgsqlTypes = "ANYNONARRAY"
	PG_AUTHID        PgsqlTypes = "PG_AUTHID"
	PG_AUTH_MEMBERS  PgsqlTypes = "PG_AUTH_MEMBERS"
	_TXID_SNAPSHOT   PgsqlTypes = "_TXID_SNAPSHOT"
	UUID             PgsqlTypes = "UUID"
	_UUID            PgsqlTypes = "_UUID"
	TXID_SNAPSHOT    PgsqlTypes = "TXID_SNAPSHOT"
	FDW_HANDLER      PgsqlTypes = "FDW_HANDLER"
	PG_LSN           PgsqlTypes = "PG_LSN"
	_PG_LSN          PgsqlTypes = "_PG_LSN"
	TSM_HANDLER      PgsqlTypes = "TSM_HANDLER"
	ANYENUM          PgsqlTypes = "ANYENUM"
	TSVECTOR         PgsqlTypes = "TSVECTOR"
	TSQUERY          PgsqlTypes = "TSQUERY"
	GTSVECTOR        PgsqlTypes = "GTSVECTOR"
	_TSVECTOR        PgsqlTypes = "_TSVECTOR"
	_GTSVECTOR       PgsqlTypes = "_GTSVECTOR"
	_TSQUERY         PgsqlTypes = "_TSQUERY"
	REGCONFIG        PgsqlTypes = "REGCONFIG"
	_REGCONFIG       PgsqlTypes = "_REGCONFIG"
	REGDICTIONARY    PgsqlTypes = "REGDICTIONARY"
	_REGDICTIONARY   PgsqlTypes = "_REGDICTIONARY"
	JSONB            PgsqlTypes = "JSONB"
	_JSONB           PgsqlTypes = "_JSONB"
	ANYRANGE         PgsqlTypes = "ANYRANGE"
	EVENT_TRIGGER    PgsqlTypes = "EVENT_TRIGGER"
	INT4RANGE        PgsqlTypes = "INT4RANGE"
	_INT4RANGE       PgsqlTypes = "_INT4RANGE"
	NUMRANGE         PgsqlTypes = "NUMRANGE"
	_NUMRANGE        PgsqlTypes = "_NUMRANGE"
	TSRANGE          PgsqlTypes = "TSRANGE"
	_TSRANGE         PgsqlTypes = "_TSRANGE"
	TSTZRANGE        PgsqlTypes = "TSTZRANGE"
	_TSTZRANGE       PgsqlTypes = "_TSTZRANGE"
	DATERANGE        PgsqlTypes = "DATERANGE"
	_DATERANGE       PgsqlTypes = "_DATERANGE"
	INT8RANGE        PgsqlTypes = "INT8RANGE"
	_INT8RANGE       PgsqlTypes = "_INT8RANGE"
	PG_SHSECLABEL    PgsqlTypes = "PG_SHSECLABEL"
	REGNAMESPACE     PgsqlTypes = "REGNAMESPACE"
	_REGNAMESPACE    PgsqlTypes = "_REGNAMESPACE"
	REGROLE          PgsqlTypes = "REGROLE"
	_REGROLE         PgsqlTypes = "_REGROLE"
)

type PgsqlConvertValue struct{}

// 使用类型断言或赋值来让编译器检查 MysqlConvertValue结构体是否实现某接口
var _ db_utils.ConvertValue = (*PgsqlConvertValue)(nil)

// 开发阶段：使用编译时检查 (var _ Interface = (*Type)(nil))

// 转换值为适合数据库的类型
// /Users/blue7/go/pkg/mod/github.com/lib/pq@v1.10.9/oid/types.go
// todo 每个连接对象都有一个这样的实现，里面列出了所有的pgsql的数据类型
/**

var TypeName = map[Oid]string{
	T_bool:             "BOOL",
	T_bytea:            "BYTEA",
	T_char:             "CHAR",
	T_name:             "NAME",
	T_int8:             "INT8",
	T_int2:             "INT2",
	T_int2vector:       "INT2VECTOR",
	T_int4:             "INT4",
	T_regproc:          "REGPROC",
	T_text:             "TEXT",
	T_oid:              "OID",
	T_tid:              "TID",
	T_xid:              "XID",
	T_cid:              "CID",
	T_oidvector:        "OIDVECTOR",
	T_pg_ddl_command:   "PG_DDL_COMMAND",
	T_pg_type:          "PG_TYPE",
	T_pg_attribute:     "PG_ATTRIBUTE",
	T_pg_proc:          "PG_PROC",
	T_pg_class:         "PG_CLASS",
	T_json:             "JSON",
	T_xml:              "XML",
	T__xml:             "_XML",
	T_pg_node_tree:     "PG_NODE_TREE",
	T__json:            "_JSON",
	T_smgr:             "SMGR",
	T_index_am_handler: "INDEX_AM_HANDLER",
	T_point:            "POINT",
	T_lseg:             "LSEG",
	T_path:             "PATH",
	T_box:              "BOX",
	T_polygon:          "POLYGON",
	T_line:             "LINE",
	T__line:            "_LINE",
	T_cidr:             "CIDR",
	T__cidr:            "_CIDR",
	T_float4:           "FLOAT4",
	T_float8:           "FLOAT8",
	T_abstime:          "ABSTIME",
	T_reltime:          "RELTIME",
	T_tinterval:        "TINTERVAL",
	T_unknown:          "UNKNOWN",
	T_circle:           "CIRCLE",
	T__circle:          "_CIRCLE",
	T_money:            "MONEY",
	T__money:           "_MONEY",
	T_macaddr:          "MACADDR",
	T_inet:             "INET",
	T__bool:            "_BOOL",
	T__bytea:           "_BYTEA",
	T__char:            "_CHAR",
	T__name:            "_NAME",
	T__int2:            "_INT2",
	T__int2vector:      "_INT2VECTOR",
	T__int4:            "_INT4",
	T__regproc:         "_REGPROC",
	T__text:            "_TEXT",
	T__tid:             "_TID",
	T__xid:             "_XID",
	T__cid:             "_CID",
	T__oidvector:       "_OIDVECTOR",
	T__bpchar:          "_BPCHAR",
	T__varchar:         "_VARCHAR",
	T__int8:            "_INT8",
	T__point:           "_POINT",
	T__lseg:            "_LSEG",
	T__path:            "_PATH",
	T__box:             "_BOX",
	T__float4:          "_FLOAT4",
	T__float8:          "_FLOAT8",
	T__abstime:         "_ABSTIME",
	T__reltime:         "_RELTIME",
	T__tinterval:       "_TINTERVAL",
	T__polygon:         "_POLYGON",
	T__oid:             "_OID",
	T_aclitem:          "ACLITEM",
	T__aclitem:         "_ACLITEM",
	T__macaddr:         "_MACADDR",
	T__inet:            "_INET",
	T_bpchar:           "BPCHAR",
	T_varchar:          "VARCHAR",
	T_date:             "DATE",
	T_time:             "TIME",
	T_timestamp:        "TIMESTAMP",
	T__timestamp:       "_TIMESTAMP",
	T__date:            "_DATE",
	T__time:            "_TIME",
	T_timestamptz:      "TIMESTAMPTZ",
	T__timestamptz:     "_TIMESTAMPTZ",
	T_interval:         "INTERVAL",
	T__interval:        "_INTERVAL",
	T__numeric:         "_NUMERIC",
	T_pg_database:      "PG_DATABASE",
	T__cstring:         "_CSTRING",
	T_timetz:           "TIMETZ",
	T__timetz:          "_TIMETZ",
	T_bit:              "BIT",
	T__bit:             "_BIT",
	T_varbit:           "VARBIT",
	T__varbit:          "_VARBIT",
	T_numeric:          "NUMERIC",
	T_refcursor:        "REFCURSOR",
	T__refcursor:       "_REFCURSOR",
	T_regprocedure:     "REGPROCEDURE",
	T_regoper:          "REGOPER",
	T_regoperator:      "REGOPERATOR",
	T_regclass:         "REGCLASS",
	T_regtype:          "REGTYPE",
	T__regprocedure:    "_REGPROCEDURE",
	T__regoper:         "_REGOPER",
	T__regoperator:     "_REGOPERATOR",
	T__regclass:        "_REGCLASS",
	T__regtype:         "_REGTYPE",
	T_record:           "RECORD",
	T_cstring:          "CSTRING",
	T_any:              "ANY",
	T_anyarray:         "ANYARRAY",
	T_void:             "VOID",
	T_trigger:          "TRIGGER",
	T_language_handler: "LANGUAGE_HANDLER",
	T_internal:         "INTERNAL",
	T_opaque:           "OPAQUE",
	T_anyelement:       "ANYELEMENT",
	T__record:          "_RECORD",
	T_anynonarray:      "ANYNONARRAY",
	T_pg_authid:        "PG_AUTHID",
	T_pg_auth_members:  "PG_AUTH_MEMBERS",
	T__txid_snapshot:   "_TXID_SNAPSHOT",
	T_uuid:             "UUID",
	T__uuid:            "_UUID",
	T_txid_snapshot:    "TXID_SNAPSHOT",
	T_fdw_handler:      "FDW_HANDLER",
	T_pg_lsn:           "PG_LSN",
	T__pg_lsn:          "_PG_LSN",
	T_tsm_handler:      "TSM_HANDLER",
	T_anyenum:          "ANYENUM",
	T_tsvector:         "TSVECTOR",
	T_tsquery:          "TSQUERY",
	T_gtsvector:        "GTSVECTOR",
	T__tsvector:        "_TSVECTOR",
	T__gtsvector:       "_GTSVECTOR",
	T__tsquery:         "_TSQUERY",
	T_regconfig:        "REGCONFIG",
	T__regconfig:       "_REGCONFIG",
	T_regdictionary:    "REGDICTIONARY",
	T__regdictionary:   "_REGDICTIONARY",
	T_jsonb:            "JSONB",
	T__jsonb:           "_JSONB",
	T_anyrange:         "ANYRANGE",
	T_event_trigger:    "EVENT_TRIGGER",
	T_int4range:        "INT4RANGE",
	T__int4range:       "_INT4RANGE",
	T_numrange:         "NUMRANGE",
	T__numrange:        "_NUMRANGE",
	T_tsrange:          "TSRANGE",
	T__tsrange:         "_TSRANGE",
	T_tstzrange:        "TSTZRANGE",
	T__tstzrange:       "_TSTZRANGE",
	T_daterange:        "DATERANGE",
	T__daterange:       "_DATERANGE",
	T_int8range:        "INT8RANGE",
	T__int8range:       "_INT8RANGE",
	T_pg_shseclabel:    "PG_SHSECLABEL",
	T_regnamespace:     "REGNAMESPACE",
	T__regnamespace:    "_REGNAMESPACE",
	T_regrole:          "REGROLE",
	T__regrole:         "_REGROLE",
}
*/
func (pcv *PgsqlConvertValue) ConvertValue(val interface{}, colTypeName string) interface{} {
	if val == nil {
		return nil
	}

	// colType *sql.ColumnType , colType.DatabaseTypeName()
	switch PgsqlTypes(colTypeName) {
	case INT2, INT4, INT8:
		switch v := val.(type) {
		case int64:
			return v
		case []uint8: // 处理MySQL返回的[]byte
			str := string(v)
			if i, err := strconv.ParseInt(str, 10, 64); err == nil {
				return i
			}
		}
	case VARCHAR, TEXT, CHAR:
		switch v := val.(type) {
		case string:
			return v
		case []uint8:
			return string(v)
		}
	case DATE, TIME, TIMETZ, TIMESTAMPTZ, TIMESTAMP:
		switch v := val.(type) {
		case time.Time:
			return v
		case []uint8:
			if t, err := time.Parse("2006-01-02 15:04:05", string(v)); err == nil {
				return t
			}
		}
	}

	return val
}
